package com.assets.Input;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;

import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.widget.*;

import com.assets.Adapter.Addrepairs_Adapter1;
import com.assets.BaseActivity;
import com.assets.Ip_set.Url;
import com.assets.R;
import com.assets.Scan.qrcode.util.Constant;
import com.assets.Scan.zxing.activity.CaptureActivity;
import com.assets.bean.AddRepairs_bean;
import com.assets.bean.AddRepairs_bean1;
import com.assets.newNHF.util.LogUtils;
import com.assets.util.MediaUtil;
import com.assets.util.RequestSuccess;
import com.assets.util.Since_case;
import com.assets.util.TrustAllCerts;
import com.bigkoo.alertview.AlertView;
import com.bigkoo.alertview.OnDismissListener;
import com.bigkoo.alertview.OnItemClickListener;
import com.gg.reader.api.dal.GClient;
import com.gg.reader.api.protocol.gx.EnumG;
import com.gg.reader.api.protocol.gx.MsgBaseInventoryEpc;
import com.gg.reader.api.protocol.gx.MsgBaseSetBaseband;
import com.gg.reader.api.protocol.gx.MsgBaseSetPower;
import com.gg.reader.api.protocol.gx.MsgBaseStop;
import com.gg.reader.api.protocol.gx.ParamEpcReadTid;

import okhttp3.*;

import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class Rfid_Input extends BaseActivity implements OnDismissListener {
    private ImageView fh;//返回
    private String url = "http://" + Url.IP + "/api/assetScanEntry";
    private String urls = "http://" + Url.IP + "/api/assetEntryAction";
    private List<AddRepairs_bean1> data = new ArrayList<>();
    private List<String> lv_data = new ArrayList<>();//提交数据
    private Map<String, String> map = new HashMap<>();//重复查询处理
    private TextView title_text;//标题
    private ListView Supplies_list;
    private EditText input_number;
    private Handler handler = new Handler();
    private String id, rfid;//登录人id
    //播放声音
    private Button bt_scan, bt_upload, bt_Rfid;//rfid,扫码，上传
    private volatile GClient client;
    private boolean isRead = false, isOpen = false;
    private HandlerThread handlerThread = new HandlerThread("workThread");
    private Handler handlerRFID;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initData();
        initRFIDHandle();
    }

    @Override
    public int intiLayout() {
        return R.layout.rfid_input;//设置子类的布局
    }

    @Override
    public void initView() {//初始化控件
        fh = (ImageView) findViewById(R.id.fh);
        title_text = (TextView) findViewById(R.id.title_text);
        title_text.setText("入库");
        Supplies_list = (ListView) findViewById(R.id.Supplies_list);
        bt_scan = (Button) findViewById(R.id.scan);
        bt_Rfid = findViewById(R.id.btn_rfid);
        bt_upload = (Button) findViewById(R.id.upload);
        input_number = (EditText) findViewById(R.id.Input_number);
        input_number.setFocusableInTouchMode(true);
        input_number.requestFocus();
    }

    @Override
    public void initData() {//初始化数据
        SharedPreferences mm = getSharedPreferences("mm", Context.MODE_PRIVATE);//1.通过上下文得到
        id = mm.getString("id", "");
        bt_upload.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (lv_data.size() > 0) {
                    new AlertView(" 提示！", "是否上传数据", "取消", new String[]{"确定"}, null, Rfid_Input.this, AlertView.Style.Alert, new OnItemClickListener() {
                        @Override
                        public void onItemClick(Object o, int position) {
                            //取消：position=-1,确定 position=0
                            if (position == 0) {
                                uploads();
                            }
                            if (position == -1) {

                            }

                        }
                    }).setCancelable(true).setOnDismissListener(Rfid_Input.this).show();

                } else {
                    showToast("请扫描需要入库的资产");
                }

            }
        });
        input_number.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                input_number.selectAll();
                if (!input_number.getText().toString().trim().equals("") && input_number.length() > 9) {
                    String scanQrcode = input_number.getText().toString().trim();
                    if (map.containsKey(scanQrcode)) {
                        showToast("请勿重复扫码");
                    } else {
                        map.put(scanQrcode, "");
                        upload(input_number.getText().toString().trim());
                    }
                } else {
                    showToast("错误的格式");
                }
            }
        });
        fh.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
        bt_scan.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startQrCode();
            }
        });
        bt_Rfid.setOnClickListener(v -> {
            if (bt_Rfid.getText().toString().equals("开始读取")) {
                handlerRFID.post(runStartRead);
            } else {
                stop();
            }
        });
    }


    // 开始扫码
    private void startQrCode() {
        // 申请相机权限
        if (ActivityCompat.checkSelfPermission(Rfid_Input.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            // 申请权限
            ActivityCompat.requestPermissions(Rfid_Input.this, new String[]{Manifest.permission.CAMERA}, Constant.REQ_PERM_CAMERA);
            return;
        }
        // 申请文件读写权限（部分朋友遇到相册选图需要读写权限的情况，这里一并写一下）
        if (ActivityCompat.checkSelfPermission(Rfid_Input.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            // 申请权限
            ActivityCompat.requestPermissions(Rfid_Input.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, Constant.REQ_PERM_EXTERNAL_STORAGE);
            return;
        }
        // 二维码扫码
        Intent intent = new Intent(Rfid_Input.this, CaptureActivity.class);
        startActivityForResult(intent, Constant.REQ_QR_CODE);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case Constant.REQ_PERM_CAMERA:
                // 摄像头权限申请
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // 获得授权
                    startQrCode();
                } else {
                    // 被禁止授权
                    Toast.makeText(Rfid_Input.this, "请至权限中心打开本应用的相机访问权限", Toast.LENGTH_LONG).show();
                }
                break;
            case Constant.REQ_PERM_EXTERNAL_STORAGE:
                // 文件读写权限申请
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // 获得授权
                    startQrCode();
                } else {
                    // 被禁止授权
                    Toast.makeText(Rfid_Input.this, "请至权限中心打开本应用的文件读写权限", Toast.LENGTH_LONG).show();
                }
                break;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        //扫描结果回调
        if (requestCode == Constant.REQ_QR_CODE && resultCode == RESULT_OK) {
            Bundle bundle = data.getExtras();
            final String scanResult = bundle.getString(Constant.INTENT_EXTRA_KEY_QR_SCAN);
            //将扫描出的信息显示出来
            if (map.containsKey(scanResult)) {
                showToast("请勿重复扫码");
            } else {
                map.put(scanResult, "");
                upload(input_number.getText().toString().trim());
            }
        }
    }

    private void getRFIDData(String epc) {
        if (map.containsKey(epc)) return;
        map.put(epc, "");
        Map<String, String> map = new HashMap<>();
        map.put("rfid", epc);
        post(Url.assetRfidEntry(), map, responseData -> {
            handleAssetData(responseData);
        }, () -> {
            map.remove(epc);
        });
    }

    private void upload(final String scanResult) {
        if (lv_data.contains(scanResult)) {
            showToast("该资产已存在列表");
            return;
        }
        OkHttpClient client = new OkHttpClient
                .Builder()
                .hostnameVerifier(new AllowAllHostnameVerifier())
                .sslSocketFactory(TrustAllCerts.createSSLSocketFactory(), TrustAllCerts.getX509TrustManager())
                .connectTimeout(10, TimeUnit.SECONDS)//连接超时
                .readTimeout(500, TimeUnit.SECONDS)
                .build();//创建OkHttpClient对象。
        FormBody.Builder formBody = new FormBody.Builder();//创建表单请求体
        formBody.add("assetNumber", scanResult); //传递键值对参数
        Request request = new Request.Builder()//创建Request 对象。
                .url(url)
                .post(formBody.build())//传递请求体
                .build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                //回调方法的使用与get异步请求相同
                Log.i("123123", "error");
                map.remove(scanResult);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                final String responseData = response.body().string();
                //回调方法的使用与get异步请求相同
                handleAssetData(responseData);
            }
        });
    }

    private void handleAssetData(String responseData) {
        try {
            Log.i("123123", responseData);
            JSONObject json = new JSONObject(responseData);
            Bitmap bitmap = null;
            if (json.getString("state").equals("0")) {
                showToast("失败");
            }
            if (json.getString("state").equals("1")) {
                JSONObject jsonObject = json.getJSONObject("asset");
                String assetName = jsonObject.getString("assetName");
                String deptId = jsonObject.getString("deptId");
                String assetNumber = jsonObject.getString("assetNumber");
                if (lv_data.contains(assetNumber)) {
                    showToast("该资产已存在列表");
                    return;
                }
                lv_data.add(assetNumber);
                String userId = jsonObject.getString("userId");
                String model = jsonObject.getString("model");
                String type = jsonObject.getString("type");
                String remark = jsonObject.getString("remark");
                String image = "";
                if (!TextUtils.isEmpty(jsonObject.getString("image"))) {
                    image = "http://" + Url.IP + jsonObject.getString("image");
                    LogUtils.d(image);
                }
                Collections.reverse(data);
                data.add(new AddRepairs_bean1(image, assetName, deptId, assetNumber, userId, model, type, remark, "类别", ""));
                Collections.reverse(data);
                Addrepairs_Adapter1 adapter_item = new Addrepairs_Adapter1(Rfid_Input.this, R.layout.addrepairs_item, data, "入库");
                runOnUiThread(() -> Supplies_list.setAdapter(adapter_item));
            }
            if (json.getString("state").equals("2")) {
                showToast("资产不存在");
            }
            if (json.getString("state").equals("3")) {
                showToast("此资产已入库");
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    private void uploads() {
        new Thread(() -> {
            OkHttpClient client = new OkHttpClient
                    .Builder()
                    .hostnameVerifier(new AllowAllHostnameVerifier())
                    .sslSocketFactory(TrustAllCerts.createSSLSocketFactory(), TrustAllCerts.getX509TrustManager())
                    .connectTimeout(10, TimeUnit.SECONDS)//连接超时
                    .readTimeout(500, TimeUnit.SECONDS)
                    .build();//创建OkHttpClient对象。
            FormBody.Builder formBody = new FormBody.Builder();//创建表单请求体
            formBody.add("assetNumbers", lv_data.toString())
                    .add("userId", Since_case.getInstance().getUserId()); //传递键值对参数
            Request request = new Request.Builder()//创建Request 对象。
                    .url(urls)
                    .post(formBody.build())//传递请求体
                    .build();
            client.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    //回调方法的使用与get异步请求相同
                    Log.i("123123", "error");
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    final String responseData = response.body().string();
                    //回调方法的使用与get异步请求相同
                    handler.post(() -> {
                        try {
                            Log.i("123123", responseData);
                            JSONObject json = new JSONObject(responseData);
                            if (json.getString("state").equals("0")) {
                                showToast("失败");
                            }
                            if (json.getString("state").equals("1")) {
                                showToast("上传成功");
                                finish();
                            }
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    });
                }
            });

        }).start();
    }

    @Override
    public void onDismiss(Object o) {

    }


    private void initRFIDHandle() {
        handlerThread.start();
        handlerRFID = new Handler(handlerThread.getLooper());
    }

    private Runnable runStartRead = () -> {
        if (client == null) {
            init8155Rfid();
        }
        read();
    };

    private synchronized void init8155Rfid() {
        if (client == null) {
            client = new GClient();
            isOpen = client.openCusAndroidSerial("/dev/ttysWK0:115200", 64, 100);
            if (isOpen) {
// 订阅标签上报事件
                client.onTagEpcLog = (readName, logBaseEpcInfo) -> {
// 回调内部如有阻塞，会影响 API 正常使用
// 标签回调数量较多，请将标签数据先缓存起来再作业务处理
                    if (!isRead) return;
                    if (null != logBaseEpcInfo && 0 == logBaseEpcInfo.getResult()) {
                        rfid = logBaseEpcInfo.getEpc();
                        getRFIDData(rfid);
                        handlerRFID.removeCallbacks(runRFID);
                        handlerRFID.postDelayed(runRFID, 100);
                    }
                };
// 取消订阅标签上报事件
                client.onTagEpcOver = (s, logBaseEpcOver) -> LogUtils.d("Epc log over.");
                setBaseBand();
            }
        }
    }

    private synchronized void read() {
        if (!isOpen) return;
        if (isRead) {
            return;
        }
// 1 个天线读卡, 读取 EPC 数据区以及 TID 数据区
        MsgBaseInventoryEpc msgBaseInventoryEpc = new MsgBaseInventoryEpc();
        msgBaseInventoryEpc.setAntennaEnable(EnumG.AntennaNo_1);
        msgBaseInventoryEpc.setInventoryMode(EnumG.InventoryMode_Inventory);//无限轮询
        //msgBaseInventoryEpc.setInventoryMode(0);//只读取一遍
        ParamEpcReadTid tid = new ParamEpcReadTid();
        tid.setMode(EnumG.ParamTidMode_Auto);
        tid.setLen(6);
        msgBaseInventoryEpc.setReadTid(tid);
        client.sendSynMsg(msgBaseInventoryEpc);
        if (0 == msgBaseInventoryEpc.getRtCode()) {
            isRead = true;
            bt_Rfid.setText("停止RFID");
            LogUtils.d("Inventory epc successful.");
        } else {
            LogUtils.d("Inventory epc error.");
        }
    }

    private void stop() {
        if (!isOpen) return;
        // 停止指令，空闲态
        if (isRead) {
            MsgBaseStop msgBaseStop = new MsgBaseStop();
            client.sendSynMsg(msgBaseStop);
            if (0 == msgBaseStop.getRtCode()) {
                isRead = false;
                bt_Rfid.setText("开始读取");
                LogUtils.d("Stop successful.");
            } else {
                LogUtils.d("Stop error.");
            }
        }
    }

    private void setPower() {
        // 功率配置, 将 1 个天线功率设置为 30dBm.
        MsgBaseSetPower msgBaseSetPower = new MsgBaseSetPower();
        Hashtable<Integer, Integer> hashtable = new Hashtable<>();
        hashtable.put(1, 30);
        msgBaseSetPower.setDicPower(hashtable);
        client.sendSynMsg(msgBaseSetPower);
        if (0 == msgBaseSetPower.getRtCode()) {
            LogUtils.d("Power configuration succ essful.");
        } else {
            LogUtils.d("Power configuration error.");
        }
    }

    private void setBaseBand() {
        MsgBaseSetBaseband msgBaseSetBaseband = new MsgBaseSetBaseband();
        msgBaseSetBaseband.setqValue(0);
        msgBaseSetBaseband.setSession(1);
        client.sendSynMsg(msgBaseSetBaseband);
    }

    //rfid获取到数据后调用
    private Runnable runRFID = new Runnable() {
        @Override
        public void run() {
            MediaUtil.getInstance().play();
            handlerRFID.removeCallbacks(this);
        }
    };

    @Override
    protected void onPause() {
        super.onPause();
        stop();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        try {
            stop();
            if (client != null) {
                client.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            handlerRFID.removeCallbacksAndMessages(null);
            handlerThread.quit();
        }
    }
}
